package socket;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import service.ClientCommand;
import service.MessageHandler;
import service.ServerAction;

public class ChatServerClientThread extends Thread {
        private Socket connection = null;
        private ServerAction serverAction;
        private ChatChannel channel;
        
        public ChatServerClientThread(Socket connection, ChatChannel channel){
                this.connection = connection;
                this.channel = channel;
        }
        
        public void run(){
                boolean authenticated = false;
                
                ObjectOutputStream out = null;
                ObjectInputStream in = null;
                
                MessageHandler messageHandler = null;
                MessageHandler handler;
                
                String message;
                
                try {
                        out = new ObjectOutputStream(connection.getOutputStream());
                        in = new ObjectInputStream(connection.getInputStream());
                        handler = new MessageHandler(out,in);
                        serverAction = new ServerAction(handler);
                
                        authenticated = serverAction.authentify(handler);
                
                        if (!authenticated)
                                return;
                        
                        messageHandler = new MessageHandler(out, in);
                        channel.addUser(messageHandler, serverAction.getLogin());
                        
                        do {
                                message = messageHandler.readMessage();
                                
                                if (ClientCommand.isCommand(message)){
                                        ClientCommand command = ClientCommand.getType(message);
                            switch (command) {
                            case exit:
                                                serverAction.exit();
                                                break;
                                                
                            case unknown:
                                serverAction.unknown();
                                break;
                                
                            case privateMessage:
                                serverAction.privateMessage(message, channel);
                                break;
                                
                            case changeChannel:
                                this.channel = serverAction.changeChannel();
                                break;
                                
                            case usersOnline:
                                serverAction.showUsersOnline();
                                break;
                                
                            case channels:
                                serverAction.showChannels();
                                break;
                            }
                                } else {
                                        serverAction.addMessageToQueue(message, "all", channel);
                                        //notifyAll();
                                }
                                
                        } while (!message.equals("/exit") && (connection != null));
                        
                }catch (IOException ioException) {
                    if (serverAction.getLogin() != null)
                        System.out.println("User " + serverAction.getLogin() + " is offline");
                
                else
                        System.out.println("Connection is lost");
                
        } catch (ClassNotFoundException e) {
                System.out.println("Message wasn't sent");
        } finally {
                try {
                        if (in != null)
                                in.close();
                        
                        if (out != null)
                                out.close();
                        
                        if (connection != null)
                                connection.close();
                        
                        channel.removeUser(serverAction.getLogin());
                } catch (IOException ioException) {
                        System.out.println("Connection is lost");
                }
        }
    }                                       
}